package fr.esiea.es_inf5042.utils;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.Writer;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;

public class SQLScriptParser {
	
	//KSE - Script's Tokens.
	private final static String INLINE_COMMENT_TOKEN  = "--";
	private final static String MULTILINE_COMMENT_START_TOKEN = "/*";
	private final static String MULTILINE_COMMENT_END_TOKEN = "*/";
	private final static String STATEMENT_SEPARATOR_TOKEN = ";";
	
	public static List<String> parse(InputStream sqlScriptStream, File cachDirectory)
	{
		List<String> sqlStatements = null;
		File rawSqlScript = null;			
		
		rawSqlScript = deleteComments(sqlScriptStream, cachDirectory);
		sqlStatements = splitStatements(rawSqlScript);
		
		return sqlStatements;		
	}

	//KSE - Delete comments from the SQL script so as ton build a raw temporary file that will be stored into application's cache. 
	private static File deleteComments(InputStream sqlScriptStream, File cachDirectory) {
		
		File rawSQLScript = null;
		Scanner in;
		Writer out;
		String readedLine;
		String splitedLine[];			
		
		try {
			
			in = new Scanner(sqlScriptStream);
			rawSQLScript = File.createTempFile("raw_sql_script", null, cachDirectory);
			out = new OutputStreamWriter(new FileOutputStream(rawSQLScript));
					
			while(in.hasNextLine())
			{
				readedLine = in.nextLine();
				
				if(readedLine.contains(INLINE_COMMENT_TOKEN))
				{													
					splitedLine = readedLine.split(STATEMENT_SEPARATOR_TOKEN, 1);
					if(splitedLine.length > 1)
					{
						splitedLine[0] = splitedLine[0].trim();
						out.write(splitedLine[0]);
					}
				}
				
				else if (readedLine.contains(MULTILINE_COMMENT_START_TOKEN))
				{
					while( !(in.nextLine().contains(MULTILINE_COMMENT_END_TOKEN)) )
						in.nextLine();
				}
				
				else
				{		
					readedLine = readedLine.trim();
					out.write(readedLine);									
				}
			}			
		
			in.close();
			out.close();
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return rawSQLScript;
	}

	//KSE - Build a list of SQL statements from a raw script.
	private static List<String> splitStatements(File rawSqlScript) {
		
		List<String> sqlStatements = null;
		StringBuilder strBuilder;
		Scanner in;		
		
		strBuilder = new StringBuilder();
		
		try {
			
			in = new Scanner(rawSqlScript);
			
			while(in.hasNextLine())			
				strBuilder.append(in.nextLine());			
			
			sqlStatements = new ArrayList<String> (Arrays.asList(strBuilder.toString().split(STATEMENT_SEPARATOR_TOKEN)));
			
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		rawSqlScript.delete();
		return sqlStatements;
	}
}
